#pragma once
#include "xKernel/IxWnd.h"
#include "xKernel/IxWndProc.h"
#include "View.h"


class CxWnd
    : public CxView
    , public IxWnd
    , public IxWndProc
    , public CFrameWindowImpl<CxWnd>
{
    typedef CFrameWindowImpl<CxWnd> __wndclass;
public:
    CxWnd();
    virtual ~CxWnd();

    BEGIN_MSG_MAP_EX_UD(CxWnd)
        MSG_WM_NCCREATE(OnNcCreate)
        MSG_WM_PAINT(OnPaint)
        MSG_WM_ERASEBKGND(OnEraseBkgnd)
        MSG_WM_MOUSEMOVE(OnMouseMove)
        MSG_WM_LBUTTONDOWN(OnLButtonDown)
        MSG_WM_LBUTTONUP(OnLButtonUp)
        MSG_WM_SIZE(OnSize)
        CHAIN_MSG_MAP(__wndclass)
    END_MSG_MAP()

    BOOL OnNcCreate(LPCREATESTRUCT lpCreateStruct);
    void OnPaint(CDCHandle dc);
    BOOL OnEraseBkgnd(CDCHandle dc);
    void OnMouseMove(UINT nFlags, CPoint point);
    void OnLButtonDown(UINT nFlags, CPoint point);
    void OnLButtonUp(UINT nFlags, CPoint point);
    void OnSize(UINT nType, CSize size);
    void OnFinalMessage(HWND hWnd);

public:
    // interface of IxWnd
    HRESULT CreateWnd();
    HRESULT GetLayoutSchedule(IxLayoutSchedule** ppLayoutSchedule);

//     // interface of IxPaint
//     HRESULT STDMETHODCALLTYPE Paint(IxCanvas* pCanvas);

    // interface of IxWndProc
    HRESULT STDMETHODCALLTYPE ProcessMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* plRet, LPBOOL pbHandle);

    // interface of IxView
    HRESULT STDMETHODCALLTYPE SetBoxRect(RECT rcBox);
    HRESULT STDMETHODCALLTYPE GetAlpha(LPBYTE pbyAlpha);
    HRESULT STDMETHODCALLTYPE SetAlpha(BYTE byAlpha);
    HRESULT STDMETHODCALLTYPE GetShowState(LPBOOL pbShow);
    HRESULT STDMETHODCALLTYPE SetShowState(BOOL bShow);
    HRESULT STDMETHODCALLTYPE GetVisibleState(LPBOOL pbVisible);
    HRESULT STDMETHODCALLTYPE SetFocus();
    HRESULT STDMETHODCALLTYPE GetFocusState(LPBOOL pbFocus);

    // interface of IxSchedule
    HRESULT STDMETHODCALLTYPE ScheduleLayout(IxView* pView);
    HRESULT STDMETHODCALLTYPE SchedulePaint(IxView* pView);
    HRESULT STDMETHODCALLTYPE Invalidate(RECT rcDirty);

protected: 
    void _init();
    void _uninit();
    void _reset_canvas(const CSize& size);

protected:
    CComPtr<IxCanvas>           m_spCanvas;
    CComPtr<IxLayoutSchedule>   m_spLayoutSchedule;
    CComPtr<IxPaintSchedule>    m_spPaintSchedule;
    CComPtr<IxMsgDispatcher>    m_spMsgDispatcher;
};


[
    default(IxWnd),
    threading(free),
    uuid("282DF7B2-7756-4f0f-A788-78B4F230DC1B"),
    coclass
]
class CCoWnd : public CxWnd
{
public:
    DECLARE_PROTECT_FINAL_CONSTRUCT()
    DECLARE_GET_CONTROLLING_UNKNOWN()

    BEGIN_COM_MAP(CCoWnd)
        WND_INTERFACE()
    END_COM_MAP()

    HRESULT FinalConstruct()
    {
        return S_OK;
    }

    void FinalRelease()
    {}
};